{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# NumPy 中的矩阵和向量\n",
    "numpy **ndarray** 类用于表示矩阵和向量。要在 numpy 中构造矩阵，我们在列表中列出矩阵的行，并将该列表传递给 numpy 数组构造函数。"
   ]
  },
  {
   "attachments": {
    "numpyLA4.png": {
     "image/png": "iVBORw0KGgoAAAANSUhEUgAAAHAAAABjCAIAAADMwBMpAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAFh0lEQVR4nO2dP0zyThjHr2/eBENCNBoTNQ7gxOSfSXRFF+OuYYDNxMFJl7IYJ5a6MaELDAZinGpYGjraETcwMYJG0ASPgSau/Q33e3n5gS298gDV3/PZaO/u+fbr03LXh4uCYRgEgePXuAX8NNBQYNBQYNBQYNBQYNBQYNBQYNBQYNBQYH6PJaogCBZn3bx4s1ZOMEPBGU+GMtyciWZYaGbJixkKDBoKDBoKDBoKDBoKDBoKjEsN1XU9l8vFYjFBEOLx+P39PVf3crkci8XGI8MYB9ahW62WJEmaplUqFU3TWGNN0+yMXKlUCoUCyKXxynCvoZqmlUql9sd6vU4IiUajdkZutVqGYUiSNPil8cpwr6GyLHcdEUWRSyqIobwy2EW58Rm6u7vbdWRmZiYajX4LGW40tBdK6c7OzrhV2JMx4H3hDK7QlFJ2MfbHB7nleWWwi/oGGaooiqZp09PT30LGOF/f2aFarRJCQqHQ8ELous6yj+HxeObn5x3LcHWGNpvNm5ubvb29oUahlAY6uLq6GkSGezNU13VFUQ4ODoYdyO/3G+avjXlluDRDdV1PpVLb29s+n699kHcBOhYZLs3QVCo1OTnZKb3RaMzOztrs3vlMHLUM2LmFTaxDZ7NZM5v6jkwplWWZtc9ms5VKxbFIXhnsrGCMo1LG6lljCT08sEg3FNBQYNBQYNBQYNBQYNBQYKwMjcfjI9PxYzCdh6qqGg6H6/V676sXgKj/t3moruvhcJgQ8vz8PFJRf3h7e7u8vBQEQRCEXC6n67rNjqzwq6rq7e0tV8cunBeizVZdbOGVzWYdL90ssAhtGAalVJKkUqnUrgnblNFqtUhHpVfTNFEUWR3UPo4L0aaG1ut1SZLY+wWbxVterOVqmtbpAvvT2hm2tyUhpLd4aY3jQrSpoZIk1ev1dguuYg5XbLOzXRELhYIoin3HZOkpSVLnQcfFJceGdj9Dy+Xy4uIi+yJig768vFg8MYR+nJ+fcz2CCCFddZtisXh0dNS3F7ul1tbWOg+yj6yAMRq634dmMpmTk5NONQ8PD6urq2b9K5WKdQCPxzOIPlVVI5GInZnG09OT2an393e/3z+IDPv8x1BVVbe2ttoJsrCwQAjJ5/MW5ZThCS2Xy4lEIpPJEEIopYNUPT8/P+F09eGvobqup9Pp5eXlYrHY2SKTySSTyc4awGgIBoPJZPLw8HBjY0NRlGGX6qD4a2g+nz87O+vKOEppIpGo1WrBYPDL/n0fT19WZW3i8/lCoVA2m7W+Sxher9dZFFj+NbRarb6+vvaK3tzcJIQ8Pj6aGRoIBKwDSJJ0fHw8iMSVlZX9/f10Om3dbG5uzuzU0tLSIAK4+EUI0XX99PQ0Eon0nmZ/9uvra7P+fScTA7pJCJmYmGA/e7OG3VtdX03s48i+kQghpFgsMrmyLH85AWTNLi4uACekbEybjWVZLhQKdlp+ObF3ttiDnNiPAIvQbL3YrlayZZvN5WPv0pMQwrv0ZPD+ItX4c1Guq8tPTU3VarVAICCKIpvD2X9o+Hw+SqmiKB8fH16vt9FoUEp55yfNZvPu7i6RSBBCcrnc+vo61xMDy8hgYBl5KKChwKChwKChwKChwKChwKChwKChwLjaUMe1XKjdyE5Gc7DOHZy+oR3XcgF3I/OO5mpDHddyAXcj847GLsqlt7zjigtsqcbBaC419PuChgKDhgKDhgLjujf2o8fObmT7YIb2343MBWZon93IvGCGAuNqQx1vKobajexktMHXZw7oG9rxpmLA3ci8o7FmWEYGA8vIQwENBQYNBQYNBQYNBQYNBWacS0+z/6vh5ukU/i+QUTOeif0PBjMUGDQUGDQUGDQUGDQUGDQUGDQUGDQUGDQUGDQUmH8AUWbqL1NHieoAAAAASUVORK5CYII="
    },
    "numpyLA5.png": {
     "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEYAAABjCAIAAACpLeFWAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAEMklEQVR4nO2bv0v7ThjHLyIoQlVaOoiLOghudhB01boUnd3iUgdBJ6fkD3DKX9B2cWvmQJaSTkIKDilSOBw0LmkGSZHc5JTPcHxjqenlh/3kc9fvvbZL8+S5d+6563NPr0IQBGC+WPjXHZg9XBILcEkswCWxAJfEAou5eRIEgfBp8iSG/BzAR2kG/D6lJDwBD+AcjhKXxAJcEgtwSbnjum6r1RIEQRAEVVURQvE2QV5kcOd5nqIoEELbtg3DAAC02+1YF1RLMk3T9/2w2W63yU/ALqgOvN3d3UKhEDbL5bIkSbFWVEsqFovjTcuybm9vY62EIK86Hk7AMrvrdrt7e3sbGxuxLqieSxgIoSiK2NzzvFgXDEgKgsD3fdM0QbIVj4rAQwh5nhc2l5aWIgNMVVVd1x8eHsguqBgl27bHe6YoSuRtEEJyh7F53lvASLa2toIEwbK8vMz8Ij7BYDCoVquxt9ErqdfrybL8/v6Om67rvry8HBwcxBpSEXiRrK+vO46zvb0tSVK1Wi0Wi3d3d0kMqVjxZuuC3sDLDJfEAlwSC8yhpEUAAELo9fUVALC/v/+v+zMDFlRVXV1drVQquF5BIQihRIWh/1i4uLj4e73Jxmg0Esa4ubkZr0DEQmNC1Ol0NE1bWVnBzZ2dnVTm1EnCYfab2Ple8Z6fn2VZxmPdarVc151FD1Pz9PT09vbW6/Wyd2A8j2w2m3iLjxkOh4TNI4HIbWnojszEc8j1k0hbIQgCnMBKknR/fw8A6Pf7lUoFK6zX6z97HO5hphFZPEiYibuu+/X1NRgMzs/P8RXf9xMuD9+1B9wef7XhTcnfUMJXmPx+3/ebzSaIqwr9dBGdPSiKkuSt/FUKhUK9XhdFUdf1VIakFW9a7SJb4GXj+vr66OiIUOiKIJgeeIZhEMaXwG+WhwlwPSxV4H2PUlgc7Ha7AABJko6Pj8lvIQc+Pz/xjErOIgAAQvj4+Hh1deU4zubmpuM4hmFM05MzhmGcnJyks0kbCZlJ4g4PSBjwlmUlX+4COsv8EEK8JomiqGmaZVkZXPCiFwtwSSzAJbEAl8QCXFLuIIRUVb28vBQEQZblfr8fb5M5wUlLBne+7yuKYpqmbdthUcQ0TbILqiWZpgkhDJvD4RAAIIoi2QXVkjRNm7iCk1qyC6rn0tnZ2cSVUqkUnieaBtWSfuJ5Xq1WI9/D0uZiNBqVSiXP8ybO6U24YGmUOp2OaZrT9IRQUeZPctILV9oODw/jH5d+6coIwV3sSS98FDmhCwbmEkJI1/VarRZbGWdjLiGEGo3G6enpuB5yWkTFXCLQaDTW1tbGNXx8fJTLZZLNr+dIUjK4w2fdfzLtRyf8KQNzKa0L2udSBrgkFuCSWGAOJeX9VTvtH+bJF/f/43/U8/uqzY05HCUuiQW4JBbgkliAS2KBOZT0ByMMvlkVuuPSAAAAAElFTkSuQmCC"
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 用 numpy 求解方程组\n",
    "线性代数中比较常见的问题之一是求解矩阵向量方程。\n",
    "例：我们寻求解决方程的向量 x：\n",
    "Ax = b 当 ![numpyLA4.png](attachment:numpyLA4.png)\n",
    "\n",
    "![numpyLA5.png](attachment:numpyLA5.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.]\n",
      " [-1.]\n",
      " [ 2.]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "# 首先构造 A 和 b 的数组\n",
    "A = np.array([[2, 1, -2], [3, 0, 1], [1, 1, -1]])\n",
    "b = np.transpose(np.array([[-3, 5, -2]]))\n",
    "\n",
    "# 求解方程组\n",
    "x = np.linalg.solve(A, b)\n",
    "print(x)"
   ]
  },
  {
   "attachments": {
    "numpyLA6.png": {
     "image/png": "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"
    },
    "numpyLA7.png": {
     "image/png": "iVBORw0KGgoAAAANSUhEUgAAAEkAAAB7CAIAAAC3ozotAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAE4klEQVR4nO2cP0/qXhjHn97cBBcS42A0mmg0URMT0LgYYxz8sxjjoIsTvA54AywQB0dcdGpXy6Y4UpwghoROFhNicSgh9AX0Ds/vxwWkh/YA9Rzv+UzH1vN8++U5PS3PaZEcx4Efyq/vPoAJIrzxifDGJ8IbnwhvfPI7MCVJkgh7KW6PyAFB5G2cjPH2lRAKU/qT8ya88YnwxifCG5+w4s227dvbW0mS4vG4ruu40TTNeDyey+XoYrLiLRwOX1xcAEAkEtnY2MCNoVAoEomcnZ1RBnWCwotcLBbr/h9Zlg3DoNZiJW/I6ekpAJimCQDNZrNery8vL1NHY8tbNBoFgPf3dwB4fHy8vLzs3qvrejKZ9B6NLW8LCwsAUKlUms2mbdvdSavVaq1WK5VK+QhHMZrp8CiXSCQAQJZly7L6dhmG4fGAUYutvAHA8fExNmZmZkYMxZy3lZUVADg5ORk9FHPeWq2WLMujJw0Y9JbP5/FKMDpseXt+ft7e3g6Hw2OJxoS3eDwuSVIymSyVSoeHh+MKG3QtaCB4WYtGo4TRaJrm09MTAOi6Pjs76+WElJyg1k2x9hSMnKhz8YzwxifCG58Ib3wivE0eUZ/0if/CByVe5ER90itseSPUJ3O5nCRJkiRlMhk0PxS2vLnVJ8vl8uLiouM4lmW9vr7e3Nx4CkcxmunwKDewPlkqlTrtarU6NA5qsZU3cKlPbm1tddpTU1M45QyHOg9+8SiHxeOvReUOqqp2p5GgxVzeyPVJ27YLhUJ3Gkn4/vxp8SiXTqfb7bbbXlVVCXv7tNjKG7k+qSjKzs6O9+olE9681CcVRTk4OJifnwcA27bL5fLwuDilIqqqWpbVbrdVVcUtHx8f/kbesHEycFdn3ncbb7Is9x02YbLpaIHjOJqmYbsz/+AWTdNIPd1Jp9O+vI0d1PoNAJubm/jH9fX13d0dADw8PADA2trawEPHaZpAKBQa6j8I0GhnEBqGYVkWACQSiUl8luONSdb6bz1gb28PGy8vL0tLSwBwfn4e5Ec8Cf6uByiKcnV1BQCxWOz+/r7dbrvNtrVajRw0FArhhNajFPh6wN9B0n0WZbPZoRknwMhc0iOWTqdx49AbNmq9sYclaPVcu4+OjrCxurpKORpYosfb9PQ0AGSz2XGtyn4vPd4qlQoA7O/vf9PBDEBRFEmSPBYR+umMUbysxWKxiZ4DdL3c7pDIvfpvMqrVql95X3p+exmGoWmal+81X7UA04Xk83m/2n71Jhf/q5ZYy/8+TNMsFou2bVP0ZT1v2EvTtN3dXb+9WM8bfivF23e/sJ63UbRYz9soCG/fh5gnB/diPW9inhysxXreRkF44xPhjU+ENz4R3iaPeA7PJ8EUnhxvdS7xHJ5X2PJGfk/YL2x5I7wnrOt6JpMpFov4sKGnCYZiNNPhUY7wnjD8vzBQKpXI6xaoxVbewP09YTwJ8dt3vV7HDJNhzpvbe8Kfn5+ddqPRwDOTDHPe3J7Dq9frnSXrt7c3L1UG5ry5vSdcKBTW19exnUql5ubmhoZiy5vbc3i6rqdSqUaj0Ww2cYZsNBrDw40y9fmCIIe3I4lEYuDDG9Ra3LwnTIGo4fGJ8MYnwhufBH0NcPuRVor585/+vdfgrm/B85PzJrzxifDGJ8IbnwhvfPKTvf0B9hpVW1l5hwMAAAAASUVORK5CYII="
    },
    "numpyLA8.png": {
     "image/png": "iVBORw0KGgoAAAANSUhEUgAAALkAAAA7CAIAAACot7zYAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAEGUlEQVR4nO3cv06zXhgH8IP5jXbRxNjExFevoImTi0O9CJ3aazBOuDh2oTcgXkCZYZSujHUwKQ4WJqpDiYEL4B2e90ealh6etkB5fb+fCQ/wcMr59vAnqpIkiQBg2Nt1B+CvgawAF7ICXMgKcCErwIWsABeyAlzICnAhK8D1X2VHUhRFshavj6snHxGxNCiYV4CrunmFYP6oD8lYZE45mFeAC1kBLmQFuJAV4EJWgAtZAa7aZcV13W63u+teQAalshce9MguOZzv+5PJ5Pr6Wr4ZVCBzsGo0rxweHrbbbU3Tdt0RyFajrDQajV13AWRqlBWouZ+QldfXV0VRFEWxLCuO4+FwqCjKcDiM47hWNctQZT/3wjB8fn6m43W7XXoMURSl3+/7vl/48crQarVs2xZCnJycNBqNyWQSBEG73d7molZGzTJU2s8kSZIkUVWVfgyCQAihqmqyWm5NTdNW7SUpS+jeNnezBVEUUbcHg8F4PF5392pqBkHgOE4URfOHcBwnCAJJS/X9TFYM1p+fKSIpeV+9PJm7l5qVJEno62Xb9gb7VlOTzoDjOGmL4zgLp2W5pfp+JisG68/9SrPZpOMJIUzTbDabkmnjVx757iU5Pz8XQoxGo+VVrus+PDwUWNOyLLpq9/v96XTKrDYYDIQQp6enacvx8XHavqplm34WLE0NTWVkfp4sNarLNptXgiDQdZ1Osed586s8z6Mva1E1R6PRaDRKkmQ2m3U6Hfn1ugKSzz4ejzVNcxyH1qqqOpvNTNMUvNuMxcZ0Sdf1NCu6rksK1e0aFEWRrutRFHmeJ7Lulqi9qJoUFDIejzdIYYFyP7v4/6pHtxlpyuXdlmWFvnm2baeJWUjociGJbe5t6S47d7NUFEWapqXppKgtTy2F10wrdzodfuVi5faT8kHL8ych94RkDtaeECIMw8vLy06n0263b25uaLvHx8dVz+i5n+H+/j43T8vCMLQsq9frCSEMw+A8sfu+T9vv7+9TBWp/enra+IF/rZpvb293d3ebHWhLnH5+fX2l239/f2cur8HzPPoq01RG12BaparqWg9vclSzqGpr2eAaxBFF0c5vVuRM00zn+FXLmTIHq7rB+3lZMU2zjIeAAqmqapqmfDlT5mD9hHf8O2EYxsXFRd1e485zXbfX631+fsZxTMvv7+/pMrWvVbBGv79SHt/3z87OCjy0YRhXV1f0GimO44+Pj1arVVTxOsgcrKr/lqx60+n05eVFCOG67tHR0cHBwZYFDcO4vb2db6FH0B/vn5hXYF11/704qDlkBbiQFeBCVoALWQEuZAW4kBXgqvpd3Kr/UYb3LtXL/X9xCzCvAFd1723hb4d5BbiQFeBCVoALWQEuZAW4kBXgQlaAC1kBLmQFuJAV4PoNq3e7pYBRrCQAAAAASUVORK5CYII="
    }
   },
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 应用：多元线性回归\n",
    "在多元回归问题中，我们寻找一种能够将输入数据点映射到结果值的函数。每个数据点是特征向量(x1, x2, ..., xm)，由两个或多个捕获输入的各种特征的数据值组成。为了表示所有输入数据以及输出值的向量，我们设置了输入矩阵 X 和输出向量 y:\n",
    "![numpyLA6.png](attachment:numpyLA6.png)![numpyLA7.png](attachment:numpyLA7.png)\n",
    "\n",
    "在建党的最小二乘线性回归模型中，我们寻找向量 **β**，使得乘积 Xβ 最接近结果向量 **y**。\n",
    "一旦我们构建了 **β** 向量，我们就可以使用它将输入数据映射到预测结果。给定表单中的输入向量：\n",
    "![numpyLA8.png](attachment:numpyLA8.png)\n",
    "\n",
    "我们可以计算预测结果值\n",
    "![numpyLA8.png](attachment:numpyLA8.png)\n",
    "\n",
    "计算 β 向量的公式是：\n",
    "β = (X<sup>T</sup>X)<sup>-1</sup>X<sup>T</sup>y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将使用 numpy 构造适当的矩阵和向量并求解 **β** 向量。一旦解决了 **β**，可以使用它来预测最初输入数据集中遗漏的一些测试点。\n",
    "假设在 numpy 中构造了输入矩阵 X 和结果向量 y，下面代码将计算 **β** 向量："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0. ]\n",
      " [0.5]]\n"
     ]
    }
   ],
   "source": [
    "X = np.array([[1, 2], [3, 4]])\n",
    "y = np.array([[1],[2]])\n",
    "Xt = np.transpose(X)\n",
    "XtX = np.dot(Xt, X)\n",
    "Xty = np.dot(Xt, y)\n",
    "beta = np.linalg.solve(XtX, Xty)\n",
    "print(beta)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下例使用的数据集是 Windsor 房价数据集，输入变量涵盖了可能对房价产生影响的一系列因素，例如批量大小，卧室数量以及各种设施的存在。[数据集网站](https://vincentarelbundock.github.io/Rdatasets/datasets.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[-4.14106096e+03]\n",
      " [ 3.55197583e+00]\n",
      " [ 1.66328263e+03]\n",
      " [ 1.45465644e+04]\n",
      " [ 6.77755381e+03]\n",
      " [ 6.58750520e+03]\n",
      " [ 4.44683380e+03]\n",
      " [ 5.60834856e+03]\n",
      " [ 1.27979572e+04]\n",
      " [ 1.24091640e+04]\n",
      " [ 4.19931185e+03]\n",
      " [ 9.42215457e+03]]\n",
      "prediction = 97360.65509691094actual = 82500.0\n",
      "prediction = 71774.16590136985actual = 83000.0\n",
      "prediction = 92359.0891976023actual = 84000.0\n",
      "prediction = 77748.274237906actual = 85000.0\n",
      "prediction = 91015.59030664092actual = 85000.0\n",
      "prediction = 97545.1179047323actual = 91500.0\n",
      "prediction = 97360.65509691094actual = 94000.0\n",
      "prediction = 106006.80075598108actual = 103000.0\n",
      "prediction = 92451.69312694679actual = 105000.0\n",
      "prediction = 73458.29493810149actual = 105000.0\n"
     ]
    }
   ],
   "source": [
    "import csv\n",
    "import numpy as np\n",
    "\n",
    "def readData():\n",
    "    X = []\n",
    "    y = []\n",
    "    with open('Housing.csv') as f:\n",
    "        rdr = csv.reader(f)\n",
    "        # 跳过首行\n",
    "        next(rdr)\n",
    "        # 读取 X 和 y\n",
    "        for line in rdr:\n",
    "            xline = [1.0]\n",
    "            for s in line[:-1]:\n",
    "                xline.append(float(s))\n",
    "            X.append(xline)\n",
    "            y.append(float(line[-1]))\n",
    "    return (X, y)\n",
    "\n",
    "X0, y0 = readData()\n",
    "# 将原始数据除最后 10 行转为空数据\n",
    "d = len(X0) - 10\n",
    "X = np.array(X0[:d])\n",
    "y = np.transpose(np.array([y0[:d]]))\n",
    "\n",
    "# 计算 β\n",
    "Xt = np.transpose(X)\n",
    "XtX = np.dot(Xt, X)\n",
    "Xty = np.dot(Xt, y)\n",
    "beta = np.linalg.solve(XtX, Xty)\n",
    "print(beta)\n",
    "\n",
    "# 对数据集最后 10 行进行预测\n",
    "for data, actual in zip(X0[d:], y0[d:]):\n",
    "    x = np.array([data])\n",
    "    prediction = np.dot(x, beta)\n",
    "    print('prediction = ' + str(prediction[0, 0]) + 'actual = ' + str(actual))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
